import IdCard from "@/utils/idCard";
import {FormItemConfig} from "@/types/form";

class FormRules {
    private isInput(item: FormItemConfig) {
        return (
            item.component === "Input" &&
            (item.componentProps?.inputType || item.componentProps?.type)
        );
    }

    private isInputNumber(item: FormItemConfig) {
        return this.isInput(item) && item.componentProps?.type === "number";
    }

    private isInputEmail(item: FormItemConfig) {
        return this.isInput(item) && item.componentProps?.inputType === "email";
    }

    private isInputPhone(item: FormItemConfig) {
        return this.isInput(item) && item.componentProps?.inputType === "phone";
    }

    private isInputIdCard(item: FormItemConfig) {
        return this.isInput(item) && ["id", "idCard"].includes(item.componentProps?.inputType);
    }

    private isInputPeople(item: FormItemConfig) {
        return this.isInput(item) && item.componentProps?.inputType === "people";
    }

    private isInputFee(item: FormItemConfig) {
        return this.isInput(item) && item.componentProps?.inputType === "fee";
    }

    private isInputPassword(item: FormItemConfig) {
        return (
            item.component === "InputPassword" &&
            item.componentProps?.inputType &&
            item.componentProps?.inputType === "password"
        );
    }

    private isDateRelation(item: FormItemConfig) {
        return item.component === "DatePicker" && item.relation;
    }

    private isTimeJudge(item: any) {
        return item.component === "DatePicker" && item.componentProps?.judge;
    }

    private validateLength(str: any, options: any) {
        const {minlength, maxlength, suffix} = options;
        if (!minlength && !maxlength) return "";
        const suffixTitle = `${suffix ? suffix : "数字"}`;
        // 构建一个正则表达式，匹配至少 minLength 个数字，最多 maxLength 个
        const regex = new RegExp(
            minlength && maxlength
                ? `^.{${minlength},${maxlength}}$`
                : minlength
                    ? `^.{${minlength},}$`
                    : `^.{0,${maxlength}}$`
        );
        const title: any =
            minlength && maxlength
                ? `${minlength}~${maxlength}之间的${suffixTitle}`
                : minlength
                    ? `至少${minlength}位数${suffixTitle}`
                    : `最多${maxlength}位数${suffixTitle}`;
        // 使用正则表达式检查字符串是否为数字且长度符合要求
        return regex.test(str) ? "" : `请输入${title}`;
    }

    private validateNumber(str: any, options: any) {
        const {minNumber, maxNumber, suffix} = options;
        if (!minNumber && !maxNumber) return "";
        const suffixTitle = `${suffix ? suffix : "数字"}`;
        if ((minNumber || minNumber === 0) && maxNumber) {
            return Number(str) >= minNumber && Number(str) <= maxNumber
                ? ""
                : `请输入${minNumber}~${maxNumber}之间的${suffixTitle}`;
        } else if (minNumber) {
            return Number(str) >= minNumber
                ? ""
                : `请输入${minNumber}以内的${suffixTitle}`;
        } else {
            return Number(str) <= maxNumber
                ? ""
                : `请输入大于${minNumber}的${suffixTitle}`;
        }
    }

    private validateInputNumber(item: FormItemConfig, rule: any, value: any, cb: (options?: any) => void) {
        const lengthError = this.validateLength(value, item.componentProps);
        const numberError = this.validateNumber(value, item.componentProps);
        if (lengthError) {
            cb(new Error(lengthError));
        } else if (numberError) {
            cb(new Error(numberError));
        } else {
            cb();
        }
    }

    private validateInputIdCard(item: FormItemConfig, rule: any, value: any, cb: (options?: any) => void) {
        if (!IdCard.identityCodeValid(value)) {
            cb(new Error(`请输入正确的${item.label}`))
        } else {
            cb();
        }
    }

    private createNumberRules(item: FormItemConfig) {
        this.createRuleKey(item);
        const ruleList: any = {
            validator: (rule: any, value: any, cb: (options?: any) => void) =>
                this.validateInputNumber(item, rule, value, cb),
            trigger: ["change", "blur"]
        };
        item.formItemProps.rules.push(ruleList);
    }

    private createEmailRules(item: any) {
    }

    private createTimeJudgeRules(item: FormItemConfig) {
        if (!item.componentProps) return;
        item.componentProps["pickerOptions"] = {
            ...item.componentProps?.pickerOptions,
            disabledDate: (time: any) => {
                return item.componentProps?.judge === ">"
                    ? time.getTime() > Date.now()
                    : time.getTime() < Date.now();
            }
        };
    }

    private createPeopleRules(item: FormItemConfig) {
        this.createRuleKey(item);
        const ruleList: any = {
            pattern: /^[0-9]*[1-9][0-9][0-9][0-9][0-9]*$/,
            trigger: ["change", "blur"],
            message: `请输入正确的${item.label
                .replace("：", "")
                .replace(/[0-9]、/g, "")}`
        };
        item.formItemProps.rules.push(ruleList);
    }

    private createFeeRules(item: FormItemConfig) {
        this.createRuleKey(item);
        const ruleList: any = {
            pattern: /^\d+(\.\d+)?$/,
            trigger: ["change", "blur"],
            message: `请输入正确的${item.label
                .replace("：", "")
                .replace(/[0-9]、/g, "")}`
        };
        item.formItemProps.rules.push(ruleList);
    }

    private createPasswordRules(item: FormItemConfig) {
        this.createRuleKey(item);
        const ruleList: any = {
            validator: (rule: any, value: any, cb: (options?: any) => void) =>
                this.validateInputNumber(item, rule, value, cb),
            trigger: ["change", "blur"]
        };
        item.formItemProps.rules.push(ruleList);
    }

    private createPhoneRules(item: FormItemConfig) {
        this.createRuleKey(item);
        const ruleList: any = {
            pattern: /^1[3456789]\d{9}$/,
            message: `请输入正确的${item.label
                .replace("：", "")
                .replace(/[0-9]、/g, "")}`
        };
        const hasRule = item.formItemProps.rules.find((rule: any) => rule.pattern === ruleList.pattern);
        if (!hasRule) {
            item.formItemProps.rules.push(ruleList);
        }
    }

    private createIdCardRules(item: FormItemConfig) {
        this.createRuleKey(item);
        const ruleList: any = {
            validator: (rule: any, value: any, cb: (options?: any) => void) =>
                this.validateInputIdCard(item, rule, value, cb),
            trigger: ["change", "blur"]
        };
        item.formItemProps.rules.push(ruleList);
    }

    // 判断是否有规则，没有则创建
    private createRuleKey(item: FormItemConfig) {
        if (!item.formItemProps.rules) {
            item.formItemProps["rules"] = [];
        }
    }

    createRules(item: FormItemConfig) {
        if (this.isInputPhone(item)) this.createPhoneRules(item);
        if (this.isInputPassword(item)) this.createPasswordRules(item);
        if (this.isInputPeople(item)) this.createPeopleRules(item);
        if (this.isInputFee(item)) this.createFeeRules(item);
        if (this.isTimeJudge(item)) this.createTimeJudgeRules(item);
        if (this.isInputIdCard(item)) this.createIdCardRules(item);
    }
}

export default new FormRules();
